﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;

namespace simpleCheckTrace
{
    class Program
    {


        static void Main(string[] args)
        {
            if (args.Length > 0)
            {
                if (args[0].Contains("eely"))
                {
                    #region Geely - OnOff Trace Check
                    string[] raw_traces;
                    int fileCounter;
                    Boolean instrFlag;
                    string resultFile;
                    resultFile = "result.result";
                    Regex rg = new Regex(@"[?*]: \S+");

                    instrFlag = false;
                    fileCounter = 1;

                    Console.WriteLine("## Program started...");
                    Console.WriteLine("-- Search possible files to analyze...");

                    raw_traces = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.txt", SearchOption.TopDirectoryOnly);

                    if (raw_traces.Length > 0)
                    {
                        foreach (string traceFile in raw_traces)
                        {
                            Console.WriteLine("-- start to analyze " + fileCounter.ToString() + " file");

                            try
                            {
                                using (StreamReader sr = new StreamReader(traceFile))
                                {
                                    string line;
                                    while ((line = sr.ReadLine()) != null)
                                    {
                                        if (line.Contains("Boot from flash"))
                                        {
                                            instrFlag = true;
                                            continue;
                                        }

                                        if (instrFlag)
                                        {
                                            if (!(line.Contains("Booting from UART") || rg.Matches(line).Count > 0))
                                            {
                                                //didn't find a normal startup.
                                                Console.WriteLine("-- Find: " + line);
                                            }
                                            instrFlag = false;
                                        }
                                    }

                                }

                            }
                            catch (Exception err)
                            {
                                Console.WriteLine("** Error: " + err.Message);
                                Console.WriteLine("** Skip current file analyze.");
                            }

                            finally
                            {
                                fileCounter += 1;

                            }

                        }
                        Console.ReadLine();
                    }
                    else
                    {
                        Console.WriteLine("-- No Trace file found.");
                        Console.WriteLine("-- Press any key to quit.");
                        Console.ReadLine();
                        return;
                    }
            #endregion Geely
                }
                else {
                    #region BMW fileSystem Check

                    Dictionary<string, ulong> dic = new Dictionary<string, ulong>();

                    string[] rawFiles;
                    string beforeFile;
                    string afterFile;
                    string curDir;
                    //Boolean fileReadyFlag;
                    string tmpLine;
                    string debugString;
                    string fName;
                    ulong fLength;
                    int unblankCount;
                    long lineNumber;

                    lineNumber = 1;


                    fLength = 0;
                    fName = "";
                    curDir = "";
                    unblankCount = 0;
                    tmpLine = "";
                    debugString = "";
                    beforeFile = "";
                    afterFile = "";
                    //fileReadyFlag = false;
                    Regex fileReg = new Regex(@"^(-r).*");
                    Regex contentReg = new Regex(@"\S*");
                    Regex dirReg = new Regex(@"^(./)\S*");
                    MatchCollection debugMC = contentReg.Matches("");


                    Console.WriteLine("## Program started...");
                    Console.WriteLine("-- Search possible files to analyze...");

                    rawFiles = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.txt", SearchOption.TopDirectoryOnly);

                    foreach (string fileName in rawFiles)
                    {
                        if (fileName.Contains("Before"))
                        {
                            Console.WriteLine("-- Find File system log before flash");
                            beforeFile = fileName;
                        }

                        if (fileName.Contains("After"))
                        {
                            Console.WriteLine("-- Find File system log after flash");
                            afterFile = fileName;
                        }
                    }

                    if (File.Exists(beforeFile) && File.Exists(afterFile))
                    {
                        Console.WriteLine("-- analyzing file system log before flash");

                        //try
                        //{
                        using (StreamReader sr = new StreamReader(beforeFile))
                        {
                            string line;
                            while ((line = sr.ReadLine()) != null)
                            {
                                if (dirReg.IsMatch(line))
                                {
                                    curDir = line.Replace(":", "");
                                }
                                try
                                {
                                    tmpLine = line;
                                    if (fileReg.Matches(line).Count > 0)
                                    {
                                        if (contentReg.IsMatch(line))
                                        {
                                            MatchCollection mc = contentReg.Matches(line);
                                            for (int i = 0; i < mc.Count; i++)
                                            {
                                                if (mc[i].Value.Length > 0)
                                                {
                                                    unblankCount += 1;
                                                    if (unblankCount == 5)
                                                    {
                                                        fLength = ulong.Parse(mc[i].Value);
                                                    }
                                                    if (unblankCount == 9)
                                                    {
                                                        fName = mc[i].Value;

                                                    }
                                                }
                                            }
                                            unblankCount = 0;

                                            debugMC = mc;
                                            //debugString = contentReg.Matches(line)[9].Value;
                                            //long fLength = long.Parse(contentReg.Matches(line)[9].Value);
                                            //debugString = contentReg.Matches(line)[18].Value.ToString();
                                            //string fName = contentReg.Matches(line)[18].Value.ToString();
                                            //long fLength = long.Parse(line.Split(' ')[4]);
                                            //string fName = line.Split(' ')[8];
                                            dic[curDir + "/" + fName] = fLength;
                                        }
                                    }
                                    lineNumber += 1;
                                }
                                catch (Exception err)
                                {
                                    if (err.Message.Contains("key was not present"))
                                    {
                                        Console.WriteLine("-- Find newly add file: line is NO." + lineNumber.ToString() + ": [" + tmpLine + "]");
                                        continue;
                                    }


                                    Console.WriteLine("*** Error: " + err.Message);
                                    Console.WriteLine("*** now quit the operation.");
                                    Console.WriteLine("*** Error line is NO." + lineNumber.ToString() + ": [" + tmpLine + "]");
                                    Console.WriteLine("*** possible Error var is: [" + debugString + "]");
                                    Console.WriteLine("*** last MC recall:");
                                    for (int i = 0; i < debugMC.Count; i++)
                                    {
                                        Console.WriteLine("\t var" + i.ToString() + ": " + debugMC[i].Value);
                                    }

                                    return;
                                }
                            }
                        }
                        Console.WriteLine("-- analyze file system log before flash done.");
                        lineNumber = 1;
                        Console.WriteLine("-- analyzing file system log after flash");

                        using (StreamReader sr = new StreamReader(afterFile))
                        {
                            string line;
                            while ((line = sr.ReadLine()) != null)
                            {
                                if (dirReg.IsMatch(line))
                                {
                                    curDir = line.Replace(":", "");
                                }
                                try
                                {
                                    tmpLine = line;
                                    if (fileReg.Matches(line).Count > 0)
                                    {
                                        if (contentReg.IsMatch(line))
                                        {
                                            MatchCollection mc = contentReg.Matches(line);
                                            for (int i = 0; i < mc.Count; i++)
                                            {
                                                if (mc[i].Value.Length > 0)
                                                {
                                                    unblankCount += 1;
                                                    if (unblankCount == 5)
                                                    {
                                                        fLength = ulong.Parse(mc[i].Value);
                                                    }
                                                    if (unblankCount == 9)
                                                    {
                                                        fName = curDir + "/" + mc[i].Value;
                                                    }
                                                }
                                            }
                                            unblankCount = 0;
                                            //Console.WriteLine("=====Debug: fLengthAfter:[" + fLength.ToString() + "]" + " fName:[" + fName + "]" + " fLengthbefore:[" + dic[fName].ToString() + "]");
                                            //if(fLength != dic[fName])
                                            if (fLength > 5000 && fLength != dic[fName])
                                            {
                                                Console.WriteLine("-- Find: " + fName + "[before: " + dic[fName].ToString() + "] [after: " + fLength.ToString() + "]");
                                            }
                                            debugMC = mc;
                                            //debugString = contentReg.Matches(line)[9].Value;
                                            //long fLength = long.Parse(contentReg.Matches(line)[9].Value);
                                            //debugString = contentReg.Matches(line)[18].Value.ToString();
                                            //string fName = contentReg.Matches(line)[18].Value.ToString();
                                            //long fLength = long.Parse(line.Split(' ')[4]);
                                            //string fName = line.Split(' ')[8];
                                            //dic[fName] = fLength;
                                        }
                                    }
                                    //if (fileReg.Matches(line).Count > 0) {
                                    //    debugString = contentReg.Matches(line)[9].Value;
                                    //    fLength = long.Parse(contentReg.Matches(line)[9].Value);
                                    //    debugString = contentReg.Matches(line)[18].Value.ToString();
                                    //    fName = contentReg.Matches(line)[18].Value.ToString();
                                    //    //long fLength = long.Parse(line.Split(' ')[4]);
                                    //    //string fName = line.Split(' ')[8];
                                    //    if (System.Math.Abs(fLength - dic[fName]) > (dic[fName] / 2)) {
                                    //        Console.WriteLine("-- Find: " + fName + "[before: " + dic[fName].ToString() + "] [after: " + fLength.ToString() + "].");
                                    //    }
                                    //}
                                    lineNumber += 1;
                                }
                                catch (Exception err)
                                {
                                    if (err.Message.Contains("key was not present"))
                                    {
                                        Console.WriteLine("-- Find newly add file: " + curDir + ": [" + tmpLine + "]");
                                        continue;
                                    }


                                    Console.WriteLine("*** Error: " + err.Message);
                                    Console.WriteLine("*** now quit the operation.");
                                    Console.WriteLine("*** Error line is NO." + lineNumber.ToString() + ": [" + tmpLine + "]");
                                    Console.WriteLine("*** possible Error var is: [" + debugString + "]");
                                    Console.WriteLine("*** last MC recall:");
                                    for (int i = 0; i < debugMC.Count; i++)
                                    {
                                        Console.WriteLine("\t var" + i.ToString() + ": " + debugMC[i].Value);
                                    }

                                    return;
                                }
                            }
                        }
                        Console.WriteLine("-- analyze file system log after flash done.");

                    }
                    //catch (Exception err) {
                    //    if (err.Message.Contains("key was not present")) {
                    //        Console.WriteLine("-- Find newly add file: line is NO." + lineNumber.ToString() + ": [" + tmpLine + "]");
                    //        continue;
                    //    }


                        //    Console.WriteLine("*** Error: " + err.Message);
                    //    Console.WriteLine("*** now quit the operation.");
                    //    Console.WriteLine("*** Error line is NO." + lineNumber.ToString()+ ": [" + tmpLine + "]");
                    //    Console.WriteLine("*** possible Error var is: [" + debugString + "]");
                    //    Console.WriteLine("*** last MC recall:");
                    //    for (int i = 0; i < debugMC.Count; i++) { 
                    //        Console.WriteLine("\t var" + i.ToString() + ": " + debugMC[i].Value);
                    //    }

                        //        return;
                    //}

                    else
                    {
                        Console.WriteLine("*** Error: file system log files not ready.");
                        Console.WriteLine("*** now quit the operation.");
                        return;
                    }


                    #endregion
                }
            }
            else {
                return;
            }

        }
    }
}
